package com.ezops.dtcc.model;

import java.util.Date;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class AckNack implements Comparable<AckNack> {
	private final static Logger LOGGER = Logger.getLogger(AckNack.class);

	protected String fileName;
	protected String repository;
	protected String submitted_for_prefix;
	protected String submitted_for_value;
	protected String data_submitter_prefix;
	protected String data_submitter_value;
	protected String primary_asset_class;
	protected String product_id_prefix;
	protected String product_id_value;
	protected String source;
	protected String message_id;
	protected String event_id;
	protected String usi_prefix;
	protected String usi_value;
	protected String uti_prefix;
	protected String uti;
	protected String prior_usi_prefix;
	protected String prior_usi_value;
	protected String prior_uti_prefix;
	protected String prior_uti;
	protected String trade_party1_transaction_id;
	protected String trade_party2_transaction_id;
	protected String message_type;
	protected String action;
	protected String transaction_type;
	protected String trade_party1_role;
	protected String trade_party1_prefix;
	protected String trade_party1_value;
	protected String trade_party2_role;
	protected String trade_party2_prefix;
	protected String trade_party2_value;
	protected Date execution_timestamp;
	protected Date trade_date;
	protected Date effective_date;
	protected String verification_type;
	protected Date confirmation_datetime;
	protected String confirmation_type;
	protected Date as_of_datetime;
	protected Date valuation_datetime;
	protected String mandatory_clearing_indicator;
	protected String party1_reporting_obligation;
	protected String party2_reporting_obligation;
	protected String reporting_jurisdiction;
	protected String party1_voluntary_submission;
	protected String party2_voluntary_submission;
	protected String ack_or_nack;
	protected String reason_code;
	protected String reason_description;
	protected String net_reporting_obligation;
	protected String cftc_expected;
	protected String cftc_actual;
	protected String cftc_deviation;
	protected String esma_expected;
	protected String esma_actual;
	protected String esma_deviation;
	protected String asset_class;
	protected String fpml;
	protected Date insert_timestamp;
	protected Date update_timestamp;
	protected long timestamp_difference_in_minutes;
	
	protected String reporting_purpose;
	protected Date creation_timestamp;

	protected Document doc;
	protected XPath xpath;

	public AckNack() {
		doc = null;
		xpath = null;
		fileName = "";
	}
	
	public AckNack(Document doc, XPath xpath, String fileName) {
		this.doc = doc;
		this.xpath = xpath;
		this.fileName = fileName;
	}
	
	public void setRepository(String repository) {
		this.repository = repository;
	}

	public String getRespository() {
		return repository;
	}

	public void setSubmittedForPrefix(String submitted_for_prefix) {
		this.submitted_for_prefix = submitted_for_prefix;
	}

	public String getSubmittedForPrefix() {
		return submitted_for_prefix;
	}

	public void setSubmittedForValue(String submitted_for_value) {
		this.submitted_for_value = submitted_for_value;
	}

	public String getSubmittedForValue() {
		return submitted_for_value;
	}

	public void setDateSubmitterPrefix(String data_submitter_prefix) {
		this.data_submitter_prefix = data_submitter_prefix;
	}

	public String getDateSubmitterPrefix() {
		return data_submitter_prefix;
	}

	public void setDateSubmitterValue(String data_submitter_value) {
		this.data_submitter_value = data_submitter_value;
	}

	public String getDateSubmitterValue() {
		return data_submitter_value;
	}

	public void setPrimaryAssetClass(String primary_asset_class) {
		this.primary_asset_class = primary_asset_class;
	}

	public String getPrimaryAssetClass() {
		return primary_asset_class;
	}

	public void setProductIdPrefix(String product_id_prefix) {
		this.product_id_prefix = product_id_prefix;
	}

	public String getProductIdPrefix() {
		return product_id_prefix;
	}

	public void setProductIdValue(String product_id_value) {
		this.product_id_value = product_id_value;
	}

	public String getProductIdValue() {
		return product_id_value;
	}

	public void setSource(String source) {
		this.source = source;
	}

	public String getSource() {
		return source;
	}

	public void setMessageId(String message_id) {
		this.message_id = message_id;
	}

	public String getMessageId() {
		return message_id;
	}

	public void setEventId(String event_id) {
		this.event_id = event_id;
	}

	public String getEventId() {
		return event_id;
	}

	public void setUsiPrefix(String usi_prefix) {
		this.usi_prefix = usi_prefix;
	}

	public String getUsiPrefix() {
		return usi_prefix;
	}

	public void setUsiValue(String usi_value) {
		this.usi_value = usi_value;
	}

	public String getUsiValue() {
		return usi_value;
	}

	public void setUtiPrefix(String uti_value) {
		this.usi_prefix = uti_prefix;
	}

	public String getUtiPrefix() {
		return uti_prefix;
	}

	public void setUti(String uti) {
		this.uti = uti;
	}

	public String getUti() {
		return uti;
	}

	public void setPriorUsiPrefix(String prior_usi_prefix) {
		this.prior_usi_prefix = prior_usi_prefix;
	}

	public String getPriorUsiPrefix() {
		return prior_usi_prefix;
	}

	public void setPriorUsiValue(String prior_usi_value) {
		this.prior_usi_value = prior_usi_value;
	}

	public String getPriorUsiValue() {
		return prior_usi_value;
	}

	public void setPriorUtiPrefix(String prior_uti_prefix) {
		this.prior_uti_prefix = prior_uti_prefix;
	}

	public String getPriorUtiPrefix() {
		return prior_uti_prefix;
	}

	public void setPriorUti(String prior_uti) {
		this.prior_uti = prior_uti;
	}

	public String getPriorUti() {
		return prior_uti;
	}

	public void setTradeParty1TransactionId(String trade_party1_transaction_id) {
		this.trade_party1_transaction_id = trade_party1_transaction_id;
	}

	public String getTradeParty1TransactionId() {
		return trade_party1_transaction_id;
	}

	public void setTradeParty2TransactionId(String trade_party2_transaction_id) {
		this.trade_party2_transaction_id = trade_party2_transaction_id;
	}

	public String getTradeParty2TransactionId() {
		return trade_party2_transaction_id;
	}

	public void setMessageType(String message_type) {
		this.message_type = message_type;
	}

	public String getMessageType() {
		return message_type;
	}

	public void setAction(String action) {
		this.action = action;
	}

	public String getAction() {
		return action;
	}

	public void setTransactionType(String transaction_type) {
		this.transaction_type = transaction_type;
	}

	public String getTransactionType() {
		return transaction_type;
	}

	public void setAssetClass(String asset_class) {
		this.asset_class = asset_class;
	}

	public String getAssetClass() {
		return asset_class;
	}

	public void setTradeParty1Role(String trade_party1_role) {
		this.trade_party1_role = trade_party1_role;
	}

	public String getTradeParty1Role() {
		return trade_party1_role;
	}

	public void setTradeParty1Prefix(String trade_party1_prefix) {
		this.trade_party1_prefix = trade_party1_prefix;
	}

	public String getTradeParty1Prefix() {
		return trade_party1_prefix;
	}

	public void setTradeParty1Value(String trade_party1_value) {
		this.trade_party1_value = trade_party1_value;
	}

	public String getTradeParty1Value() {
		return trade_party1_value;
	}

	public void setTradeParty2Role(String trade_party2_role) {
		this.trade_party2_role = trade_party2_role;
	}

	public String getTradeParty2Role() {
		return trade_party2_role;
	}

	public void setTradeParty2Prefix(String trade_party2_prefix) {
		this.trade_party2_prefix = trade_party2_prefix;
	}

	public String getTradeParty2Prefix() {
		return trade_party2_prefix;
	}

	public void setTradeParty2Value(String trade_party2_value) {
		this.trade_party2_value = trade_party2_value;
	}

	public String getTradeParty2Value() {
		return trade_party2_value;
	}

	public void setFpml(String fpml) {
		this.fpml = fpml;
	}

	public void setExecutionTimestamp(Date execution_timestamp) {
		this.execution_timestamp = execution_timestamp;
	}

	public Date getExecutionTimestamp() {
		return execution_timestamp;
	}

	public void setTradeDate(Date trade_date) {
		this.trade_date = trade_date;
	}

	public Date getTradeDate() {
		return trade_date;
	}

	public void setEffectiveDate(Date effective_date) {
		this.effective_date = effective_date;
	}

	public Date getEffectiveDate() {
		return effective_date;
	}

	public void setVerificationType(String verification_type) {
		this.verification_type = verification_type;
	}

	public String getVerificationType() {
		return verification_type;
	}

	public void setConfirmationDateTime(Date confirmation_datetime) {
		this.confirmation_datetime = confirmation_datetime;
	}

	public Date getConfirmationDateTime() {
		return confirmation_datetime;
	}

	public void setConfirmationType(String confirmation_type) {
		this.confirmation_type = confirmation_type;
	}

	public String getConfirmationType() {
		return confirmation_type;
	}

	public void setAsOfDateTime(Date as_of_datetime) {
		this.as_of_datetime = as_of_datetime;
	}

	public Date getAsOfDateTime() {
		return as_of_datetime;
	}

	public void setValuationDateTime(Date valuation_datetime) {
		this.valuation_datetime = valuation_datetime;
	}

	public Date getValuationDateTime() {
		return valuation_datetime;
	}

	public void setMandatoryClearingIndicator(
			String mandatory_clearing_indicator) {
		this.mandatory_clearing_indicator = mandatory_clearing_indicator;
	}

	public String getMandatoryClearingIndicator() {
		return mandatory_clearing_indicator;
	}

	public void setParty1ReportingObligation(String party1_reporting_obligation) {
		this.party1_reporting_obligation = party1_reporting_obligation;
	}

	public String getParty1ReportingObligation() {
		return party1_reporting_obligation;
	}

	public void setParty2ReportingObligation(String party2_reporting_obligation) {
		this.party2_reporting_obligation = party2_reporting_obligation;
	}

	public String getParty2ReportingObligation() {
		return party2_reporting_obligation;
	}

	public void setReportingJurisdiction(String reporting_jurisdiction) {
		this.reporting_jurisdiction = reporting_jurisdiction;
	}

	public String getReportingJurisdiction() {
		return reporting_jurisdiction;
	}

	public void setParty1VoluntarySubmission(String party1_voluntary_submission) {
		this.party1_voluntary_submission = party1_voluntary_submission;
	}

	public String getParty1VoluntarySubmission() {
		return party1_voluntary_submission;
	}

	public void setParty2VoluntarySubmission(String party2_voluntary_submission) {
		this.party2_voluntary_submission = party2_voluntary_submission;
	}

	public String getParty2VoluntarySubmission() {
		return party2_voluntary_submission;
	}

	public void setAckOrNack(String ack_or_nack) {
		this.ack_or_nack = ack_or_nack;
	}

	public String getAckOrNack() {
		return ack_or_nack;
	}

	public void setReasonCode(String reason_code) {
		this.reason_code = reason_code;
	}

	public String getReasonCode() {
		return reason_code;
	}

	public void setReasonDescription(String reason_description) {
		this.reason_description = reason_description;
	}

	public String getReasonDescription() {
		return reason_description;
	}

	public void setNetReportingObligation(String net_reporting_obligation) {
		this.net_reporting_obligation = net_reporting_obligation;
	}

	public String getNetReportingObligation() {
		return net_reporting_obligation;
	}

	public void setCftcExpected(String cftc_expected) {
		this.cftc_expected = cftc_expected;
	}

	public String getCftcExpected() {
		return cftc_expected;
	}

	public void setCftcActual(String cftc_actual) {
		this.cftc_actual = cftc_actual;
	}

	public String getCftcActual() {
		return cftc_actual;
	}

	public void setCftcDeviation(String cftc_deviation) {
		this.cftc_deviation = cftc_deviation;
	}

	public String getCftcDeviation() {
		return cftc_deviation;
	}

	public void setEsmaExpected(String esma_expected) {
		this.esma_expected = esma_expected;
	}

	public String getEsmaExpected() {
		return esma_expected;
	}

	public void setEsmaActual(String esma_actual) {
		this.esma_actual = esma_actual;
	}

	public String getEsmaActual() {
		return esma_actual;
	}

	public void setEsmaDeviation(String esma_deviation) {
		this.esma_deviation = esma_deviation;
	}

	public String getEsmaDeviation() {
		return esma_deviation;
	}

	public String getFpml() {
		return fpml;
	}
	
	public void setReportingPurpose(String reporting_purpose) {
		this.reporting_purpose = reporting_purpose;
	}
	
	public String getReportingPurpose() {
		return reporting_purpose;
	}
	
	public void setCreationTimestamp(Date creation_timestamp) {
		this.creation_timestamp = creation_timestamp;
	}
	
	public Date getCreationTimeDate() {
		return creation_timestamp;
	}

	public void setInsertTimestamp(Date insert_timestamp) {
		this.insert_timestamp = insert_timestamp;
	}

	public Date getInsertTimestamp() {
		return insert_timestamp;
	}

	public void setUpdateTimestamp(Date update_timestamp) {
		this.update_timestamp = update_timestamp;
	}

	public Date getUpdateTimestamp() {
		return update_timestamp;
	}
	
	//Timestamp stored in minutes
	public void setTimestampDifference(long difference) {
		this.timestamp_difference_in_minutes = difference;
	}
	
	public long getTimestampDifference() {
		return timestamp_difference_in_minutes;
	}
	
	@Override
	public String toString() {
		return "[ Source = " + source + " Message Id = " + message_id
				+ " Event Id=" + event_id + " Message Type = " + message_type
				+ " Action = " + action + " Transaction Type = "
				+ transaction_type + " Asset Class = " + asset_class + " ]";
	}

	public int compareTo(AckNack ackNack) {
		if (message_id.equals(ackNack.getMessageId()))
			return 0;
		return 1;
	}

	protected String getXPath(String path) {
		String value = null;
		try {
			XPathExpression expr = xpath.compile("//*[local-name()='" + path + "']/text()");
			value = (String) expr.evaluate(doc, XPathConstants.STRING);
			LOGGER.info("xpath->" + path + " value->" + value);
		} catch (XPathExpressionException e) {
			LOGGER.error("Unexpected Exception while trying to xpath"
					+ e.toString());
		}
		return value.trim();
	}
	
	
	protected String getXPathAbsolute(String path) {
		String value = null;
		try {
			XPathExpression expr = xpath.compile("//*[local-name()='" + path + "']" );
			value = (String) expr.evaluate(doc, XPathConstants.STRING);
			LOGGER.info("xpath->" + path + " value->" + value);
		} catch (XPathExpressionException e) {
			LOGGER.error("Unexpected Exception while trying to xpath"
					+ e.toString());
		}
		return value.trim();
	}
	
	
	protected String getXPathAbsoluteDirect(String path) {
		String value = null;
		try {
			XPathExpression expr = xpath.compile("//"+ path );
			value = (String) expr.evaluate(doc, XPathConstants.STRING);
			LOGGER.info("xpath->" + path + " value->" + value);
		} catch (XPathExpressionException e) {
			LOGGER.error("Unexpected Exception while trying to xpath"
					+ e.toString());
		}
		return value.trim();
	}
	
	
	protected String getXPath(String element, String attribute) {
		String value = null;
		try {
			String xpathString = "" + "//*[local-name()='" + element + "']/@"+attribute;
			XPathExpression expr = xpath.compile(xpathString);
			value = (String) expr.evaluate(doc, XPathConstants.STRING);
			LOGGER.info("xpath->" + xpathString + " value->" + value);
		} catch (XPathExpressionException e) {
			LOGGER.error("Unexpected Exception while trying to xpath"
					+ e.toString());
		}
		return value.trim();
	}

	public void traverse(Node node) {
	    System.out.println("Name->"+node.getNodeName());

	    NodeList nodeList = node.getChildNodes();
	    for (int i = 0; i < nodeList.getLength(); i++) {
	        Node currentNode = nodeList.item(i);
	        if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
	            traverse(currentNode);
	        }
	    }
	}
	public void parse() throws Exception {}
}
